package com.hilton.tigershark.titlebar;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.SystemClock;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.Animation.AnimationListener;
import android.webkit.WebView;

import com.hilton.tigershark.BrowserActivity;
import com.hilton.tigershark.R;
import com.hilton.tigershark.view.CustomizedWebview;

// TODO: when find dialog is up, or when selection dialog is up, show not show and hide
public class TitlebarManager implements CustomizedWebview.OnChangedListener {
    private static final String TAG = "TitlebarManager";
    private static final long HIDE_TITLEBAR_DELAY = 1500;
    private static float V_TRIGGER_ANGLE = .9f;
    private static long SCROLL_TIMEOUT_DURATION = 150;
    private static long IGNORE_INTERVAL = 250;
    
    private TitleBar mTitleBar;
    private BrowserActivity mBrowserActivity;
    private Handler mMyHandler;
    private CustomizedWebview mTarget;
    private final int mTouchSlop;
    private float mStartTouchX;
    private float mStartTouchY;
    private boolean mTracking;
    private boolean mHasTriggered;
    private long mLastScrollTime;
    private long mTriggeredTime;
    private Animation mEnterAnimation;
    private Animation mExitAnimation;
    
    public TitlebarManager(Context context) {
        mBrowserActivity = (BrowserActivity) context;
        mTitleBar = (TitleBar) mBrowserActivity.findViewById(R.id.titlebar);
        ViewConfiguration v = ViewConfiguration.get(context);
        mTouchSlop = v.getScaledTouchSlop() * 2;
        Log.e(TAG, "titlebar touchslop " + mTouchSlop);
        mMyHandler = new Handler();
        mEnterAnimation = AnimationUtils.loadAnimation(context, R.anim.title_bar_enter);
        mEnterAnimation.setAnimationListener(new AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
                // If view is GONE, system won't play animations on it
                mTitleBar.setVisibility(View.INVISIBLE);
            }
            
            @Override
            public void onAnimationRepeat(Animation animation) {
            }
            
            @Override
            public void onAnimationEnd(Animation animation) {
                mTitleBar.setVisibility(View.VISIBLE);
            }
        });
        mExitAnimation = AnimationUtils.loadAnimation(context, R.anim.title_bar_exit);
        mExitAnimation.setAnimationListener(new AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
            }
            
            @Override
            public void onAnimationRepeat(Animation animation) {
            }
            
            @Override
            public void onAnimationEnd(Animation animation) {
                mTitleBar.setVisibility(View.GONE);
            }
        });
    }
    
    public void attachTo(CustomizedWebview v) {
        if (mTarget == v) return;
        if (mTarget != null) {
            mTarget.setOnChangeListener(null);
        }
        mTarget = v;
        if (mTarget != null) {
            mTarget.setOnChangeListener(this);
        }
    }
    
    @Override
    public void onScrollChanged(int l, int t, int oldl, int oldt) {
        if (mBrowserActivity.dialogsUp()) {
            return;
        }
        mLastScrollTime = SystemClock.uptimeMillis();
        if (t > 0) {
            // If it is showing, extend it
            if (showing()) {
                long remaining = mLastScrollTime - mTriggeredTime;
                remaining = Math.max(HIDE_TITLEBAR_DELAY - remaining, SCROLL_TIMEOUT_DURATION);
                showProvisionallyFor(remaining);
            }
        } else {
            // hit the top
            showTitleBar();
        }
    }

    private void stopTracking() {
        if (mTracking) {
            mTracking = false;
            if (showing()) {
                showProvisionally();
            }
        }
    }
    
    @Override
    public void onTouch(WebView v, MotionEvent event) {
        if (mBrowserActivity.dialogsUp()) {
            return;
        }
        if (event.getPointerCount() > 1) {
            stopTracking();
        }
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            if (!mTracking && event.getPointerCount() == 1) {
                long sinceLastScroll = SystemClock.uptimeMillis() - mLastScrollTime;
                if (sinceLastScroll < IGNORE_INTERVAL) {
                    break;
                }
                mStartTouchY = event.getY();
                mStartTouchX = event.getX();
                mTracking = true;
                mHasTriggered = false;
            }
            break;
        case MotionEvent.ACTION_MOVE:
            if (mTracking && !mHasTriggered) {
                float dy = event.getY() - mStartTouchY;
                float ady = Math.abs(dy);
                float adx = Math.abs(event.getX() - mStartTouchX);
                if (ady > mTouchSlop) {
                    mHasTriggered = true;
                    float angle = (float) Math.atan2(ady, adx);
                    if (dy > mTouchSlop && angle > V_TRIGGER_ANGLE && !showing()) {
                        mTriggeredTime = SystemClock.uptimeMillis();
                        showTitleBar();
                    }
                }
            }
            break;
        case MotionEvent.ACTION_CANCEL:
        case MotionEvent.ACTION_UP:
            stopTracking();
            break;
        }
    }
    
    private Runnable mHideCallback = new Runnable() {
        @Override
        public void run() {
            hideTitleBar();
        }
    };
    
    private boolean canShow() {
        return !showing();
    }
    
    private void showProvisionally() {
        showProvisionallyFor(HIDE_TITLEBAR_DELAY);
    }
    
    private void showProvisionallyFor(long duration) {
        showTitleBar();
        mMyHandler.postDelayed(mHideCallback, duration);
    }
    
    public void showTitleBar() {
        mMyHandler.removeCallbacks(mHideCallback);
        if (canShow()) {
            mTitleBar.startAnimation(mEnterAnimation);
        }
    }
    
    public void hideTitleBar() {
        mMyHandler.removeCallbacks(mHideCallback);
        if (showing()) {
            mTitleBar.startAnimation(mExitAnimation);
        }
    }

    private boolean showing() {
        return mTitleBar.getVisibility() == View.VISIBLE;
    }

    public void setProgress(int p) {
        mTitleBar.setProgress(p);
    }

    public void setDisplayTitle(String title) {
        mTitleBar.setDisplayTitle(title);
    }
    

    /**
     * Special method for the fake title bar to call when displaying its context
     * menu, since it is in its own Window, and its parent does not show a
     * context menu.
     */
    public void showTitleBarContextMenu() {
        if (null == mTitleBar.getParent()) {
            return;
        }
        mBrowserActivity.openContextMenu(mTitleBar);
    }

    public void toggleLockIcon(Drawable d) {
        mTitleBar.toggleLockIcon(d);
    }

    public void setFavicon(Bitmap icon) {
        mTitleBar.setFavicon(icon);
    }
}